using System;
using System.Collections.Generic;
using System.Text;

// Analysis Services
using Microsoft.AnalysisServices;

namespace Microsoft.EPM.Events
{
    class OlapRolesMgr
    {
        string CSTOLAPDefaultDataRole = "ProjectServerViewOlapDataRole";
        
        private int nbOfRoles = 0;


        public int CountOfRoles
        {
            get
            {
                return nbOfRoles;
            }
            set
            {
                nbOfRoles = value;
            }
        }



        private string ComputeFileName(string ASinstanceName, string ASDbName)
        {
            string tmpString = ASinstanceName.Replace("\\", "_");
            return tmpString + "__" + ASDbName;
        }

        private ReadAccess toReadAccess(String str)
        {
            switch (str)
            {
                case "None":
                    return ReadAccess.None;
                case "Allowed":
                    return ReadAccess.Allowed;
                default:
                    return ReadAccess.None; // just in case..
            }

        }

        private WriteAccess toWriteAccess(String str)
        {
            switch (str)
            {
                case "None":
                    return WriteAccess.None;
                case "Allowed":
                    return WriteAccess.Allowed;
                default:
                    return WriteAccess.None; // just in case..
            }

        }

        private ReadDefinitionAccess toReadDefinitionAccess(String str)
        {
            switch (str)
            {
                case "None":
                    return ReadDefinitionAccess.None;
                case "Allowed":
                    return ReadDefinitionAccess.Allowed;
                case "Basic":
                    return ReadDefinitionAccess.Basic;
                default:
                    return ReadDefinitionAccess.None; // just in case..
            }
        }

        public void SaveToFile(string ASinstanceName, string ASDbName, Database db, RoleCollection dbRoles, string LogFolder, bool logEvents, AppLog appLog)
        {
            int nbOfRoles = dbRoles.Count;

            if (dbRoles.ContainsName(CSTOLAPDefaultDataRole))
            {
                    --nbOfRoles;
            }
            CountOfRoles = nbOfRoles;

            RolesDataFile theRoleFile = new RolesDataFile(ComputeFileName(ASinstanceName, ASDbName), LogFolder, false);
            // First we write the number Of Roles
            theRoleFile.WriteLine(nbOfRoles.ToString());

            DatabasePermissionCollection dbPerms = db.DatabasePermissions;

            DimensionCollection dims = db.Dimensions;

            CubeCollection cubes = db.Cubes;

            foreach (Role myRole in dbRoles)
            {
                if (!myRole.Name.Equals(CSTOLAPDefaultDataRole))
                {
                    //SaveRole(myRole, logEvents, appLog);
                    if (logEvents)
                    {
                        appLog.WriteLine(string.Format("Role {0} has {1} members", myRole.Name, myRole.Members.Count.ToString()));
                    }
                    theRoleFile.WriteLine(myRole.Name);

                    theRoleFile.WriteLine(myRole.Members.Count.ToString());

                    // save members
                    foreach (RoleMember myMember in myRole.Members)
                    {
                        if (logEvents)
                        {
                            appLog.WriteLine(string.Format("Member {0} with SID  {1}", myMember.Name, myMember.Sid));
                        }
                        theRoleFile.WriteLine(myMember.Name);
                        theRoleFile.WriteLine(myMember.Sid);
                    }

                    //Save DB permissions
                    bool foundRolePermission = false;
                    foreach (DatabasePermission myPermission in dbPerms)
                    {
                        if (myPermission.Role.Name.Equals(myRole.Name))
                        {
                            foundRolePermission = true;
                            break;
                        }
                    }
                    if (foundRolePermission)
                    {
                        theRoleFile.WriteLine("true");
                        DatabasePermission dbPerm = dbPerms.GetByRole(myRole.ID);
                        theRoleFile.WriteLine(dbPerm.Administer.ToString());
                        theRoleFile.WriteLine(dbPerm.Process.ToString());
                        theRoleFile.WriteLine(dbPerm.Read.ToString());
                        theRoleFile.WriteLine(dbPerm.Write.ToString());
                        theRoleFile.WriteLine(dbPerm.ReadDefinition.ToString());
                    }
                    else
                    {
                        theRoleFile.WriteLine("false");
                    }

                    // save dimension permissions
                    // count number of permissions
                    int nbOfDimPermissions = 0;
                    foreach (Dimension dim in dims)
                    {
                        DimensionPermissionCollection DimPerms = dim.DimensionPermissions;
                        foreach (DimensionPermission dimPerm in DimPerms)
                        {
                            if (dimPerm.Role.Name.Equals(myRole.Name))
                            {
                                nbOfDimPermissions++;
                                break;
                            }
                        }
                    }

                    theRoleFile.WriteLine(nbOfDimPermissions.ToString());

                    if (nbOfDimPermissions > 0)
                    {
                        foreach (Dimension dim in dims)
                        {
                            DimensionPermissionCollection DimPerms = dim.DimensionPermissions;
                            foundRolePermission = false;
                            foreach (DimensionPermission dimPerm in DimPerms)
                            {
                                if (dimPerm.Role.Name.Equals(myRole.Name))
                                {
                                    foundRolePermission = true;
                                    break;
                                }

                            }
                            if (foundRolePermission)
                            {
                                DimensionPermission dimPerm = DimPerms.GetByRole(myRole.ID);
                                theRoleFile.WriteLine(dim.Name);
                                theRoleFile.WriteLine(dimPerm.Process.ToString());
                                theRoleFile.WriteLine(dimPerm.Read.ToString());
                                theRoleFile.WriteLine(dimPerm.Write.ToString());
                                theRoleFile.WriteLine(dimPerm.ReadDefinition.ToString());
                            }

                        }
                    }
                    // save cube permissions

                    // count number of permissions
                    int nbOfCubePermissions = 0;
                    foreach (Cube cube in cubes)
                    {
                        CubePermissionCollection CubePerms = cube.CubePermissions;
                        foreach (CubePermission cubePerm in CubePerms)
                        {
                            if (cubePerm.Role.Name.Equals(myRole.Name))
                            {
                                nbOfCubePermissions++;
                                break;
                            }
                        }
                    }


                    theRoleFile.WriteLine(nbOfCubePermissions.ToString());

                    if (nbOfCubePermissions > 0)
                    {
                        foreach (Cube cube in cubes)
                        {
                            CubePermissionCollection CubePerms = cube.CubePermissions;
                            foundRolePermission = false;
                            foreach (CubePermission cubePerm in CubePerms)
                            {
                                if (cubePerm.Role.Name.Equals(myRole.Name))
                                {
                                    foundRolePermission = true;
                                    break;
                                }

                            }
                            if (foundRolePermission)
                            {
                                CubePermission cubePerm = CubePerms.GetByRole(myRole.ID);
                                theRoleFile.WriteLine(cube.Name);
                                theRoleFile.WriteLine(cubePerm.Process.ToString());
                                theRoleFile.WriteLine(cubePerm.Read.ToString());
                                theRoleFile.WriteLine(cubePerm.Write.ToString());
                                theRoleFile.WriteLine(cubePerm.ReadDefinition.ToString());
                            }

                        }
                    }

                } // role /= CSTOLAPDefaultDataRole
            } // foreach role
            theRoleFile.CloseWriter();
           
        }

        public void ReadFromFile(string ASinstanceName, string ASDbName, Database db, RoleCollection myRole, string LogFolder, bool logEvents, AppLog appLog)
        {
            short nbOfRoles = 0;
            string theLine;

            RolesDataFile theRoleFile = new RolesDataFile(ComputeFileName(ASinstanceName, ASDbName), LogFolder, true);
            // First we get the number Of Roles
            
            theLine = theRoleFile.ReadLine();

            nbOfRoles = Convert.ToInt16(theLine);

            String theRoleName;
            String theUserName;
            String theSID;

            Role theRole;

            short nbOfUsers;
            bool HasDBPermissions;

            for (int i = 1; i <= nbOfRoles; i++)
            {
                theRoleName = theRoleFile.ReadLine();

                theRole = db.Roles.Add(theRoleName);


                theLine = theRoleFile.ReadLine();
                nbOfUsers = Convert.ToInt16(theLine);

                for (int j = 1; j <= nbOfUsers; j++)
                {
                    theUserName = theRoleFile.ReadLine();
                    theSID = theRoleFile.ReadLine();
                    RoleMember theRoleMember = new RoleMember(theUserName, theSID);
                    theRole.Members.Add(theRoleMember);
                }

                theRole.Update();

                // Read DB permissions
                theLine = theRoleFile.ReadLine();
                HasDBPermissions = Convert.ToBoolean(theLine);

                if (HasDBPermissions)
                {
                    DatabasePermission dbPerm;
                    dbPerm = db.DatabasePermissions.Add(theRole.ID);

                    theLine = theRoleFile.ReadLine();
                    dbPerm.Administer = Convert.ToBoolean(theLine);
                    theLine = theRoleFile.ReadLine();
                    dbPerm.Process = Convert.ToBoolean(theLine);
                    theLine = theRoleFile.ReadLine();
                    dbPerm.Read = toReadAccess(theLine);
                    theLine = theRoleFile.ReadLine();
                    dbPerm.Write = toWriteAccess(theLine);
                    theLine = theRoleFile.ReadLine();
                    dbPerm.ReadDefinition = toReadDefinitionAccess(theLine);
                    dbPerm.Update();
                }

                // Read Dimensions Permissions
                theLine = theRoleFile.ReadLine();
                short nbOfDimPermissions = Convert.ToInt16(theLine);
                for (int iCount = 1; iCount <= nbOfDimPermissions; iCount++)
                {
                    string theDim = theRoleFile.ReadLine();
                    Dimension dbDim = db.Dimensions.GetByName(theDim);

                    DimensionPermission dimPerm = dbDim.DimensionPermissions.Add(theRole.ID);
                    theLine = theRoleFile.ReadLine();
                    dimPerm.Process = Convert.ToBoolean(theLine);

                    theLine = theRoleFile.ReadLine();
                    dimPerm.Read = toReadAccess(theLine);

                    theLine = theRoleFile.ReadLine();
                    dimPerm.Write = toWriteAccess(theLine);

                    theLine = theRoleFile.ReadLine();
                    dimPerm.ReadDefinition = toReadDefinitionAccess(theLine);

                    dimPerm.Update();
                }

                // Add Cube permissions
                // Read Dimensions Permissions
                theLine = theRoleFile.ReadLine();
                short nbOfCubePermissions = Convert.ToInt16(theLine);
                for (int jCount = 1; jCount <= nbOfCubePermissions; jCount++)
                {
                    string theCube = theRoleFile.ReadLine();
                    Cube dbCube = db.Cubes.GetByName(theCube);

                    CubePermission cubePerm = dbCube.CubePermissions.Add(theRole.ID);
                    theLine = theRoleFile.ReadLine();
                    cubePerm.Process = Convert.ToBoolean(theLine);

                    theLine = theRoleFile.ReadLine();
                    cubePerm.Read = toReadAccess(theLine);

                    theLine = theRoleFile.ReadLine();
                    cubePerm.Write = toWriteAccess(theLine);

                    theLine = theRoleFile.ReadLine();
                    cubePerm.ReadDefinition = toReadDefinitionAccess (theLine);

                    cubePerm.Update();
                }
            }
            theRoleFile.CloseReader();
        }
    }
}
